package com.szyly.epusher.dingding;


import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
import com.dingtalk.api.request.OapiMessageCorpconversationGetsendresultRequest;
import com.dingtalk.api.request.OapiV2UserGetbymobileRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiMessageCorpconversationAsyncsendV2Response;
import com.dingtalk.api.response.OapiMessageCorpconversationGetsendresultResponse;
import com.dingtalk.api.response.OapiV2UserGetbymobileResponse;
import com.szyly.epusher.bean.DingDingProperties;
import com.szyly.epusher.bean.PhoneUserRet;
import com.szyly.epusher.bean.PushResult;
import com.taobao.api.ApiException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.List;


public class DingDingApi {
    private final static Logger logger = LoggerFactory.getLogger(DingDingApi.class);
    private DingDingProperties properties;
    private OapiToken token;

    public DingDingApi(DingDingProperties properties) {
        this.properties = properties;
    }

    public PushResult checkProperties() {
        if (!StringUtils.hasText(properties.getAppKey()) || properties.getAgentId() <= 0 || !StringUtils.hasText(properties.getAppSecret())) {
            return new PushResult(1000001, "参数未配置或者未配置完全");
        }
        return new PushResult(0, "ok");
    }

    public OapiToken checkToken() {
        if (token == null || token.getExpiresTime() < System.currentTimeMillis()) {
            return getToken();
        }
        return token;
    }

    public OapiToken getToken() {
        PushResult pushResult = checkProperties();
        if (pushResult.getErrCode() != 0) {
            return new OapiToken(pushResult.getErrCode(), pushResult.getErrMsg());
        }
        try {
            DingTalkClient tokenClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
            OapiGettokenRequest tokenReq = new OapiGettokenRequest();
            tokenReq.setAppkey(properties.getAppKey());
            tokenReq.setAppsecret(properties.getAppSecret());
            tokenReq.setHttpMethod("GET");
            OapiGettokenResponse gettokenResponse = tokenClient.execute(tokenReq);
            if (!gettokenResponse.isSuccess()) {
                logger.error("获取Token失败: {}", gettokenResponse.getErrmsg());
                return new OapiToken(gettokenResponse.getErrcode(), gettokenResponse.getErrmsg());
            }
            token = new OapiToken(gettokenResponse.getErrcode(), gettokenResponse.getErrmsg());
            token.setAccessToken(gettokenResponse.getAccessToken());
            token.setExpiresTime(System.currentTimeMillis() + gettokenResponse.getExpiresIn() * 800);
            logger.info("accessToken: {}", token.getAccessToken());
            return token;
        } catch (ApiException e) {
            e.printStackTrace();
            logger.error("获取Token失败: {}", e.getErrMsg());
            return new OapiToken(-1L, "获取Token失败: " + e.getErrMsg());

        }

    }

    public PushResult sendMarkdownMessageByPhone(String phoneNumber, String title, String content) {
        OapiToken oapiToken = checkToken();
        if (oapiToken.getErrcode() != 0) {
            return new PushResult(oapiToken.getErrcode(), oapiToken.getErrmsg());
        }
        OapiV2UserGetbymobileResponse userIdByPhone = getUserIdByPhone(phoneNumber);
        if (!userIdByPhone.isSuccess()) {
            return new PushResult(userIdByPhone.getErrcode(), userIdByPhone.getErrmsg());
        }

        try {
            OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
            req.setAgentId(properties.getAgentId());
            req.setUseridList(userIdByPhone.getResult().getUserid());
            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            msg.setMsgtype("markdown");
            OapiMessageCorpconversationAsyncsendV2Request.Markdown markdown = new OapiMessageCorpconversationAsyncsendV2Request.Markdown();
            markdown.setText(content);
            markdown.setTitle(title);
            msg.setMarkdown(markdown);
            req.setMsg(msg);
            return sendDingMsg(oapiToken.getAccessToken(), req);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("发送消息失败: {}", e.getMessage());

            return new PushResult(-1, "发送消息失败: " + e.getMessage());

        }

    }

    public PushResult sendTextMessageByPhone(String phoneNumber, String content) {
        OapiToken oapiToken = checkToken();
        if (oapiToken.getErrcode() != 0) {
            return new PushResult(oapiToken.getErrcode(), oapiToken.getErrmsg());
        }
        OapiV2UserGetbymobileResponse userIdByPhone = getUserIdByPhone(phoneNumber);
        if (!userIdByPhone.isSuccess()) {
            return new PushResult(userIdByPhone.getErrcode(), userIdByPhone.getErrmsg());
        }
        try {
            OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
            req.setAgentId(properties.getAgentId());
            req.setUseridList(userIdByPhone.getResult().getUserid());

            OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            msg.setMsgtype("text");
            OapiMessageCorpconversationAsyncsendV2Request.Text markdown = new OapiMessageCorpconversationAsyncsendV2Request.Text();
            markdown.setContent(content);
            msg.setText(markdown);
            req.setMsg(msg);
            return sendDingMsg(oapiToken.getAccessToken(), req);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("发送消息失败: {}", e.getMessage());
            return new PushResult(-1, "发送消息失败: " + e.getMessage());

        }


    }

    public static PushResult sendDingMsg(String token, OapiMessageCorpconversationAsyncsendV2Request req) {

        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");

            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, token);
            if (!rsp.isSuccess()) {
                logger.error("发送消息失败: {}", rsp.getErrmsg());
                return new PushResult(rsp.getErrcode(), rsp.getErrmsg());
            }
            return getSendResult(req.getAgentId(), rsp.getTaskId(),token);

        } catch (ApiException e) {
            e.printStackTrace();
            logger.error("发送消息失败: {}", e.getErrMsg());
            return new PushResult(-1, "发送消息失败: " + e.getMessage());

        }

    }

    public static PushResult getSendResult(Long agentId, Long taskId,String token) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/getsendresult");
            OapiMessageCorpconversationGetsendresultRequest req = new OapiMessageCorpconversationGetsendresultRequest();
            req.setAgentId(agentId);
            req.setTaskId(taskId);
            OapiMessageCorpconversationGetsendresultResponse rsp = client.execute(req, token);
            if (!rsp.isSuccess()) {
                logger.error("验证发送消息失败: {}", rsp.getErrmsg());
                return new PushResult(rsp.getErrcode(), rsp.getErrmsg());

            }
            logger.info("验证发送消息: {}", rsp.getBody());
            return new PushResult(0, "OK");

        } catch (ApiException e) {
            e.printStackTrace();
            logger.error("验证发送消息失败: {}", e.getErrMsg());
            return new PushResult(-1, "验证发送消息失败: " + e.getMessage());

        }
    }

    public PhoneUserRet getUserIdByPhoneNumber(String phoneNumber) {
        OapiV2UserGetbymobileResponse userIdByPhone = getUserIdByPhone(phoneNumber);
        if (userIdByPhone.getErrcode() != 0) {
            return new PhoneUserRet(userIdByPhone.getErrcode(), userIdByPhone.getErrmsg());
        }

        return new PhoneUserRet().setUserid(userIdByPhone.getResult().getUserid());
    }

    public OapiV2UserGetbymobileResponse getUserIdByPhone(String phoneNumber) {
        OapiToken oapiToken = checkToken();
        if (oapiToken.getErrcode() != 0) {
            OapiV2UserGetbymobileResponse response = new OapiV2UserGetbymobileResponse();
            response.setErrmsg(oapiToken.getErrmsg());
            response.setErrcode(oapiToken.getErrcode());
            return response;

        }
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
            req.setMobile(phoneNumber);
            OapiV2UserGetbymobileResponse rsp = client.execute(req, oapiToken.getAccessToken());
            if (!rsp.isSuccess()) {
                logger.error("获取用户[{}]ID失败: {}", phoneNumber, rsp.getErrmsg());
                return rsp;
            }
            logger.error("获取用户[{}]ID成功: {}", phoneNumber, rsp.getResult().getUserid());
            return rsp;
        } catch (ApiException e) {
            e.printStackTrace();
            logger.error("获取用户[{}]ID失败: {}", phoneNumber, e.getErrMsg());
            OapiV2UserGetbymobileResponse response = new OapiV2UserGetbymobileResponse();
            response.setErrcode(-1L);
            response.setErrmsg("获取用户ID失败: " + e.getErrMsg());

            return response;

        }
    }


    public PushResult sendTextMessages(List<String> phoneNumbers, String content) {

        StringBuilder stringBuilder = new StringBuilder();
        for (String phoneNumber : phoneNumbers) {
            PushResult pushResult = sendTextMessageByPhone(phoneNumber, content);
            if (pushResult.getErrCode() != 0) {
                stringBuilder.append(pushResult.getErrMsg() + ",");
            }
        }
        return new PushResult(0, stringBuilder.toString());
    }

    public PushResult sendMarkdownMessages(List<String> phoneNumbers, String title, String content) {
        StringBuilder stringBuilder = new StringBuilder();
        for (String phoneNumber : phoneNumbers) {
            PushResult pushResult = sendMarkdownMessageByPhone(phoneNumber, title, content);
            if (pushResult.getErrCode() != 0) {
                stringBuilder.append(pushResult.getErrMsg() + ",");
            }
        }
        return new PushResult(0, stringBuilder.toString());
    }
}
